#/***************************************************************************\
# * Copyright (C) by Keio University
# * CMakeLists.txt created in 09 2011.
# * Mail : fdesorbi@hvrl.ics.keio.ac.jp
# *
# * This file is part of the HVRL Engine Library.
# *
# * The HVRL Engine Library is free software; you can redistribute it and/or modify
# * it under the terms of the GNU Lesser General Public License as published by
# * the Free Software Foundation; either version 3 of the License, or
# * (at your option) any later version.
# *
# * The HVRL Engine Library is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU Lesser General Public License for more details.
# *
# * You should have received a copy of the GNU Lesser General Public License
# * along with this program.  If not, see <http://www.gnu.org/licenses/>.
# *
# ***************************************************************************/

#Required version
CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR)
CMAKE_POLICY(VERSION 2.6)

IF(COMMAND cmake_policy)
    CMAKE_POLICY(SET CMP0003 NEW)
ENDIF()

#Project name
SET(PROJECT_NAME HVRL)
PROJECT(${PROJECT_NAME})

SET(CPACK_PACKAGE_VENDOR "FRANCOIS de SORBIER")
SET(CPACK_PACKAGE_VERSION_MAJOR 0)
SET(CPACK_PACKAGE_VERSION_MINOR 1)
SET(CPACK_PACKAGE_VERSION_PATCH 0)
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE.txt")
SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README.txt")

SET(HVRL_INSTALL_PATH ${CMAKE_BINARY_DIR})

SET(HVRL_LIB_INSTALL_PATH ${HVRL_INSTALL_PATH}/lib)
SET(HVRL_INCLUDE_INSTALL_PATH ${HVRL_INSTALL_PATH}/include)
SET(HVRL_BIN_INSTALL_PATH ${HVRL_INSTALL_PATH}/bin)

SET(HVRL_CONFIG ${HVRL_BINARY_DIR}/HvrlConfig.cmake CACHE INTERNAL "Configuration file")
SET(HVRL_INCLUDE_DIRS "" CACHE INTERNAL "Local include directories")

if(CMAKE_CL_64)
    set(MSVC64 1)
endif()

if(CMAKE_COMPILER_IS_GNUCXX)
	set(ENABLE_PROFILING OFF CACHE BOOL "Enable profiling in the GCC compiler (Add flags: -g -pg)")
	set(USE_OMIT_FRAME_POINTER ON CACHE BOOL "Enable -fomit-frame-pointer for GCC")
    if(${CMAKE_SYSTEM_PROCESSOR} MATCHES amd64.*|x86_64.*)
        set(X86_64 1)
    endif()
    if(${CMAKE_SYSTEM_PROCESSOR} MATCHES i686.*|i386.*|x86.*)
        set(X86 1)
    endif()
    if(${CMAKE_SYSTEM_PROCESSOR} MATCHES powerpc.*)
        set(ENABLE_POWERPC ON CACHE BOOL "Enable PowerPC for GCC")
    endif ()
    if(X86 OR X86_64)
        # enable everything, since the available set of instructions is checked at runtime
        #IF ("${CMAKE_GCC_REGEX_VERSION}" VERSION_GREATER 4.5)
            SET(_USE_FAST_MATH OFF)
        #ELSE()
        #    SET(_USE_FAST_MATH ON)
        #ENDIF()
        set(USE_FAST_MATH ${_USE_FAST_MATH} CACHE BOOL "Enable -ffast-math (not recommended for GCC 4.6.x)")
        set(ENABLE_SSE ON CACHE BOOL "Enable SSE instructions")
        set(ENABLE_SSE2 ON CACHE BOOL "Enable SSE2 instructions")
        set(ENABLE_SSE3 OFF CACHE BOOL "Enable SSE3 instructions")
        set(ENABLE_SSSE3 OFF CACHE BOOL "Enable SSSE3 instructions")
        set(ENABLE_SSE41 OFF CACHE BOOL "Enable SSE4.1 instructions")
        set(ENABLE_SSE42 OFF CACHE BOOL "Enable SSE4.2 instructions")
    endif()
ENDIF()

if(MSVC)
    set(ENABLE_SSE ON CACHE BOOL "Enable SSE instructions for MSVC")
    set(ENABLE_SSE2 ON CACHE BOOL "Enable SSE2 instructions for MSVC")
    if(CMAKE_C_COMPILER MATCHES "icc")
        set(ENABLE_SSE3 OFF CACHE BOOL "Enable SSE3 instructions for ICC")
        set(ENABLE_SSE4_1 OFF CACHE BOOL "Enable SSE4.1 instructions for ICC")
    endif()
endif()

SET(HVRL_USE_CUDA ON CACHE BOOL "Enable the use of CUDA")
SET(HVRL_BUILD_TEST ON CACHE BOOL "Build tests")
SET(HVRL_BUILD_DOC ON CACHE BOOL "Build documentation")
SET(HVRL_BUILD_SAMPLES ON CACHE BOOL "Build samples")
SET(HVRL_BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)")
SET(HVRL_BUILD_WITH_DEBUG_INFO ON CACHE BOOL "Include debug info into debug libs")
SET(HVRL_BUILD_WITH_OPENNI ON CACHE BOOL "Try to include OPENNI while building")
SET(HVRL_BUILD_WITH_DEPTHSENSE OFF CACHE BOOL "Try to include DEPTHSENSE while building")


include(macros.cmake REQUIRED)

#-------------------------------------
# Check if dependencies are available
#-------------------------------------

SET(${PROJECT_NAME}_CMAKE_DIR ${${PROJECT_NAME}_CMAKE_DIR} "${${PROJECT_NAME}_SOURCE_DIR}/cmake")
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${HVRL_SOURCE_DIR}/cmake")

# Check OpenGL
IF(NOT DEFINED OPENGL_NOTFOUND OR OPENGL_NOTFOUND)
SET(OpenGL_FIND_REQUIRED ON)
FIND_PACKAGE(OpenGL REQUIRED)
IF(OPENGL_FOUND)
	MESSAGE(STATUS "Looking for OpenGL - found")
ELSE()
	MESSAGE(FATAL_ERROR "Looking for OpenGL - not found")
ENDIF()
ENDIF()

# Check GLM
IF(NOT DEFINED GLM_NOTFOUND OR GLM_NOTFOUND)
SET(GLM_FIND_REQUIRED ON)
FIND_PACKAGE(GLM)
IF(GLM_FOUND)
	MESSAGE(STATUS "Looking for GLM - found")
ELSE()
	MESSAGE(FATAL_ERROR "Looking for GLM - not found")
ENDIF()
ENDIF()

# Check OpenCV
IF(NOT DEFINED OpenCV_NOTFOUND OR OpenCV_NOTFOUND)
SET(OpenCV_FIND_REQUIRED ON)
FIND_PACKAGE(OpenCV REQUIRED)
IF(OpenCV_FOUND)
	MESSAGE(STATUS "Looking for OpenCV - found")
ELSE()
	MESSAGE(FATAL_ERROR "Looking for OpenCV - not found")
ENDIF()
ENDIF()

# Check OPENNI
IF(HVRL_BUILD_WITH_OPENNI AND (NOT DEFINED OPENNI_NOTFOUND OR OPENNI_NOTFOUND))
SET(OPENNI_FIND_REQUIRED ON)
FIND_PACKAGE(OPENNI)
IF(OPENNI_FOUND)
	MESSAGE(STATUS "Looking for OpenNI - found")
ELSE()
	MESSAGE(FATAL_ERROR "Looking for OpenNI - not found")
ENDIF()
ENDIF()

# Check DEPTHSENSE
IF(HVRL_BUILD_WITH_DEPTHSENSE AND (NOT DEFINED DEPTHSENSE_NOTFOUND OR DEPTHSENSE_NOTFOUND))
SET(DEPTHSENSE_FIND_REQUIRED ON)
FIND_PACKAGE(DEPTHSENSE)
IF(DEPTHSENSE_FOUND)
	MESSAGE(STATUS "Looking for DepthSense - found")
ELSE()
	MESSAGE(FATAL_ERROR "Looking for DepthSense - not found")
ENDIF()
ENDIF()

# GLEW
IF(NOT DEFINED GLEW_NOTFOUND OR GLEW_NOTFOUND)
SET(GLEW_FIND_REQUIRED ON)
FIND_PACKAGE(GLEW REQUIRED)
IF(GLEW_FOUND)
	MESSAGE(STATUS "Looking for GLEW - found")
ELSE()
	MESSAGE(FATAL_ERROR "Looking for GLEW - not found")
ENDIF()
ENDIF()

# freeglut
IF(HVRL_BUILD_SAMPLES AND (NOT DEFINED FREEGLUT_NOTFOUND OR FREEGLUT_NOTFOUND))
SET(FREEGLUT_FIND_REQUIRED ON)
FIND_PACKAGE(FREEGLUT REQUIRED)
IF(FREEGLUT_FOUND)
	MESSAGE(STATUS "Looking for freeglut - found")
ELSE(FREEGLUT_FOUND)
	MESSAGE(FATAL_ERROR "Looking for freeglut - not found")
ENDIF(FREEGLUT_FOUND)
ENDIF()

# Check CUDA
IF(NOT DEFINED CUDA_NOTFOUND OR CUDA_NOTFOUND)
find_package(CUDA 4.0)
SET(WITH_CUDA_AVAILABLE 0)
if(CUDA_FOUND)
	MESSAGE(STATUS "Looking for CUDA - found")
	find_package(CUTIL REQUIRED)
	if(CUTIL_FOUND)
		SET(WITH_CUDA_AVAILABLE 1)
		MESSAGE(STATUS "Looking for CUTIL - found")
	ELSE(CUTIL_FOUND)
		MESSAGE(FATAL_ERROR "Looking for CUTIL - not found")
	ENDIF(CUTIL_FOUND)
ELSE()
	MESSAGE(STATUS "Looking for CUDA - not found")
ENDIF()
ENDIF()

if(NOT HVRL_USE_CUDA)
SET(WITH_CUDA_AVAILABLE 0)
endif()

# Install thridparty libraries if necessary
ADD_SUBDIRECTORY(thirdparty)

SET(HVRL_EXTERN_LIBS ${OpenCV_LIBS} ${OPENNI_LIBRARIES} ${DEPTHSENSE_LIBRARIES} ${OPENGL_LIBRARIES} ${GLEW_LIBRARY} ${CUDA_LIBRARIES} ${CUTIL_LIBRARIES} CACHE INTERNAL "External libraries used by hvrl library")

SET(HVRL_LIBS "" CACHE INTERNAL "")

SET(HVRL_EXTERN_DIRS ${GLM_INCLUDE_DIR} ${OPENNI_INCLUDE_DIR} ${DEPTHSENSE_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${OPENNI_INCLUDE_DIR} ${OpenCV_INCLUDE_DIRS} ${GLEW_INCLUDE_PATH} ${CUDA_INCLUDE_DIRS} ${CUTIL_INCLUDE_DIR}
		    CACHE INTERNAL "External directories used by hvrl library")
INCLUDE_DIRECTORIES(${HVRL_EXTERN_DIRS} ${${PROJECT_NAME}_SOURCE_DIR}/modules)

if(CMAKE_COMPILER_IS_GNUCXX)
    if(ENABLE_PROFILING)
        set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -pg -g")
    elseif(NOT APPLE)
        set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -ffunction-sections")
    endif()

    set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -DNDEBUG")
    set(EXTRA_C_FLAGS_DEBUG "${EXTRA_C_FLAGS_DEBUG} -O0 -DDEBUG -D_DEBUG")
endif()

# Debug mode checks
IF(USE_DEBUG_MODE)
	SET(CMAKE_BUILD_TYPE debug)
ELSE(USE_DEBUG_MODE)
	MESSAGE(STATUS "Release mode")
	SET(CMAKE_BUILD_TYPE Release)
	IF(NOT WIN32)
		SET(CMAKE_CXX_FLAGS_RELEASE "-O3")
		SET(CMAKE_C_FLAGS_RELEASE "-O3")
	ENDIF()
ENDIF(USE_DEBUG_MODE)


set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_C_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${EXTRA_C_FLAGS_RELEASE}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${EXTRA_C_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_C_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${EXTRA_C_FLAGS_DEBUG}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EXTRA_EXE_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${EXTRA_EXE_LINKER_FLAGS_RELEASE}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${EXTRA_EXE_LINKER_FLAGS_DEBUG}")

#-------------------------------------
# Build the modules
#-------------------------------------

ADD_SUBDIRECTORY(modules)

#-------------------------------------
# Build the samples
#-------------------------------------
IF(HVRL_BUILD_SAMPLES)
	ADD_SUBDIRECTORY(samples)
ENDIF()



#-------------------------------------
# Build the documentation
#-------------------------------------
IF(HVRL_BUILD_DOC)
	ADD_SUBDIRECTORY (doc)
ENDIF()

CONFIGURE_FILE(HvrlConfig.cmake.in "${HVRL_CONFIG}" @ONLY)

#-------------------------------------
# Build the package
#-------------------------------------
set(HVRL_BUILD_PACKAGE ON CACHE BOOL "Enables 'make archive' command")

if(HVRL_BUILD_PACKAGE)
    set(TARBALL_NAME "${CMAKE_PROJECT_NAME}")
    if (NOT WIN32)
        if(APPLE)
            set(TAR_CMD gnutar)
        else()
            set(TAR_CMD tar)
        endif()
        set(TAR_TRANSFORM "\"s,^,${TARBALL_NAME}/,\"")
        add_custom_target(archive
        COMMAND ${TAR_CMD} --transform ${TAR_TRANSFORM} -czpf ${CMAKE_CURRENT_BINARY_DIR}/${TARBALL_NAME}.tar.gz --exclude=".svn" --exclude="*.pyc" --exclude="*.vcproj" --exclude="*/lib/*" --exclude="*.dll"  --exclude="*/build" sources/
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/..)
    else()
        add_custom_target(archive
        COMMAND zip -9 -r ${CMAKE_CURRENT_BINARY_DIR}/${TARBALL_NAME}.zip . -x '*/.svn/*' '*.vcproj' '*.pyc' '*/build/*'
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/..)
    endif()
endif()
